package com.vt.common.security.service;

import cn.hutool.core.util.StrUtil;
import com.vt.admin.api.dto.user.UserInfo;
import com.vt.admin.api.entity.SysUser;
import com.vt.admin.api.feign.RemoteUserService;
import com.vt.common.core.constant.CommonConstant;
import com.vt.common.core.constant.SecurityConstants;
import com.vt.common.core.util.R;
import com.vt.common.security.exception.UserDisabledException;
import com.vt.common.security.exception.UserNameNotFoundException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * 用户详细信息
 */
@Slf4j
@Service
@AllArgsConstructor
public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
    private final RemoteUserService remoteUserService;

    /**
     * 用户密码登录
     *
     * @param username 用户名
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        R<UserInfo> result = remoteUserService.info(username, SecurityConstants.FROM_IN);
        return getUserDetails(result);
    }

    @Override
    public UserDetails loadUserBySocial(String principal) {
        R<UserInfo> result = remoteUserService.social(principal);
        return getUserDetails(result);
    }

    @Override
    public UserDetails findUserByMobile(String mobile) {
        R<UserInfo> result = remoteUserService.mobile(mobile);
        return getUserDetails(result);
    }

    private UserDetails getUserDetails(R<UserInfo> result) {
        if (result == null || result.getData() == null) {
            throw new UserNameNotFoundException();
        }

        UserInfo info = result.getData();

        if (info.getSysUser().getUserStatus() == 0) {
            throw new UserDisabledException();
        }
        // 资源
        Set<String> dbAuthSet = new HashSet<>();
        dbAuthSet.addAll(Arrays.asList(info.getPermissions()));

        Collection<? extends GrantedAuthority> authorities
                = AuthorityUtils.createAuthorityList(dbAuthSet.toArray(new String[0]));
        SysUser user = info.getSysUser();

        // 构造security用户
        CustomUser customUser = new CustomUser(user.getId(), user.getName(), user.getAccount(),
                SecurityConstants.BCRYPT + user.getPassword(),
                StrUtil.equals(user.getUserStatus() + "", CommonConstant.STATUS_NORMAL),
                true, true, true, authorities);

        customUser.setUserType(info.getSysUser().getUserType());
        return customUser;
    }
}
